package com.fnzn.entranceGuard.rest.guard;

import cn.usr.UsrCloudMqttClientAdapter;
import com.fnzn.entranceGuard.bean.UnitHouseBean;
import com.fnzn.entranceGuard.constant.GuardConstant;
import com.fnzn.entranceGuard.entity.GuardDevice;
import com.fnzn.entranceGuard.entity.GuardIcInfo;
import com.fnzn.entranceGuard.mapper.GuardIcInfoMapper;
import com.fnzn.entranceGuard.rest.usrCloud.ClientAdapter;
import com.fnzn.entranceGuard.rest.usrCloud.UsrApi;
import com.fnzn.entranceGuard.util.QRGenerate;
import com.fnzn.entranceGuard.util.SpringUtil;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.nio.file.attribute.GroupPrincipal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author wf_sxf@163.com
 * @date 2018-05-28 9:25
 */
@Slf4j
@Component
public class UsrUtil {


    public static String device_id;
    static String username;
    static String password;

    @Value("${usr.username}")
    public String user;
    @Value("${usr.password}")
    public String pass;
    @Value("${usr.deviceId}")
    public String dev;

    @PostConstruct
    public void init() {
        username = user;
        password = pass;
        device_id = dev;
    }


    //这里使用单例模式
    public static UsrCloudMqttClientAdapter clientAdapter = null;


    public static UsrCloudMqttClientAdapter getInstance() throws Exception {
        System.out.println(clientAdapter == null);
        if (clientAdapter == null) {
            //进行连接
            synchronized (ClientAdapter.class) {
                clientAdapter = ClientAdapter.getInstance(username, password);
            }
        }
        return clientAdapter;
    }

    /**
     * 关闭连接
     *
     * @return
     * @throws MqttException
     */
    public static boolean disConnect() throws Exception {

  /* 1.初始化客户端适配 */
        UsrCloudMqttClientAdapter clientAdapter = getInstance();
  /* 2.取消连接 */
        return clientAdapter.DisConnectUnCheck();

    }

    /**
     * 推送数据到云(向单个设备）
     * <p>
     * 16进制的ascii字符串  预废弃
     *
     * @param data
     */
    @Deprecated
    public static boolean publishForDevId(String data, String deviceId) throws Exception {
         /* 1.初始化客户端适配 */
        UsrCloudMqttClientAdapter clientAdapter = getInstance();

         /*2.查看设备是否在线*/
        if(UsrApi.getDevice(deviceId)) {
             /* 3.发送数据 */
            clientAdapter.publishForDevId(deviceId, ScanUtil.Utf8strTobytes(data));
            return  true;
        }else{
            return false;
        }

    }

    /**
     * 推送数据到云(向单个设备）
     *
     * @param data
     */
    public static boolean publishForDevId(byte[] data, String deviceId) throws Exception {
         /* 1.初始化客户端适配 */
        UsrCloudMqttClientAdapter clientAdapter = getInstance();
        /*2.查看设备是否在线*/
        if(UsrApi.getDevice(deviceId)) {
             /* 3.发送数据 */
             clientAdapter.publishForDevId(deviceId, data);
             return  true;
        }else{
            return false;
        }

    }

    /**
     * 订阅账号下的所有设备
     */
    public static void SubscribeForUsername() throws Exception {
         /* 1.初始化客户端适配 */
        UsrCloudMqttClientAdapter clientAdapter = getInstance();
        //订阅设备放到连接成功后的回调函数里了
       /* *//* 2.订阅全部设备*//*
        clientAdapter.SubscribeForUsername();*/
    }

    /**
     * 生成向有人云发送报文格式
     */
    public static byte[] PublishFormat(byte[] data, byte type) throws Exception {
        if(data == null) {
            data = new byte[1];
        }
        int len = data.length;
        byte[] sendData = new byte[len + 5];
        byte[] start = QRGenerate.parse16Str2HexByte("AA");
        sendData[0] = start[0];
        sendData[1] = type;
        String l = Integer.toHexString(len);
        if (l.length() == 1) {
            l = "0" + l;
        }
        byte[] length = QRGenerate.parse16Str2HexByte(l);
        sendData[2] = length[0];
        for (int i = 0; i < len; i++) {
            sendData[3 + i] = data[i];
        }
        byte[] end = QRGenerate.parse16Str2HexByte("0D");
        sendData[3 + len] = end[0];
        sendData[4 + len] = end[0];
        return sendData;
    }

    /**
     * 0门禁 or 1梯控
     * 操作有人云，删除或新增IC卡（最长25张 100个）
     *
     * @param type  GuardConstant.TYPE  操作类型
     * @param list  要插入IC卡集合
     * @param devId 设备号
     * @param devType 设备类型(门禁：0；梯控：1)
     * @param admin 是否为管理员("admin" or null)
     * @return true插入成功 false插入失败
     */
    public static boolean addOrDelIcToDev(List<GuardIcInfo> list, String devId, byte type, String devType, String admin) throws Exception {
        try {
            StringBuilder sb = new StringBuilder();
            if(devType != null && devType.equals(GuardDevice.TYPE_GUARD)) {
                //门禁or删除
                for (int j = 0; j < list.size(); j++) {
                    sb.append(list.get(j).getIcId());
                }
            } else if (devType != null && devType.equals(GuardDevice.TYPE_ELE)) {
                //梯控
                if (admin != null && admin.equals("Admin")) {
                    //物业
                    for (int j = 0; j < list.size(); j++) {
                        sb.append(list.get(j).getIcId());
                        sb.append(63);
                    }
                } else {
                    //业主
                    GuardIcInfoMapper guardIcInfoMapper = SpringUtil.getBean(GuardIcInfoMapper.class);
                    for (int j = 0; j < list.size(); j++) {
                        UnitHouseBean unitHouseBean = guardIcInfoMapper.getFloorByHouseOwnerId(list.get(j).getHouseOwnerId());
                        sb.append(list.get(j).getIcId());
                        if(unitHouseBean!=null){
                            Integer floor = unitHouseBean.getFloor()==null ? 0:unitHouseBean.getFloor();
                            String floors = floor.toString();
                            if(floor < 10) {
                                floors = "0" + floors;
                            }
                            sb.append(floors);
                        }
                    }
                }
            }
            //调用前先查看设备在不在线
            publishForDevId(PublishFormat(QRGenerate.parse16Str2HexByte(sb.toString()), type), devId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("IC卡插入失败，" + e.getMessage());
        }
        return false;
    }

    /**
     * 根据小区编码生成16进制字节数组
     */
    public static byte[] communityCodeFormat(Integer code,GuardDevice dev) throws Exception {

        StringBuffer sb = new StringBuffer();
        if(code ==null){
            code = 0;
        }
        Integer first = code / 100;
        Integer second = code % 100;

        //电梯总层数
        if(dev.getFloor()==null){
            sb.append("00");
        }else if(dev.getFloor()<10) {
            sb.append("0" + dev.getFloor());
        }else{
            sb.append(dev.getFloor());
        }

        //社区逻辑编号
        if(first<10){
            sb.append("0"+first);
        }else{
            sb.append(first);
        }
        if(second<10){
            sb.append("0"+second);
        }else{
            sb.append(second);
        }
        //设备逻辑编号
        if(dev.getSort()==null){
            sb.append("00");
        }else if( dev.getSort()<10) {
            sb.append("0" + dev.getSort());
        }else{
            sb.append(dev.getSort());
        }

        return QRGenerate.parseStr2HexByte(sb.toString());
    }

    /**
     * 批量(超过25张卡)插入IC卡
     */
//    public static boolean batchAddIcToDev(List<GuardIcInfo> list, String deviceId) throws Exception {
//
//        try{
//
//        Integer size = list.size();
//        Integer group = size / 25;
//        Integer remainder = size % 25;
//        if (remainder > 0) {
//            group++;
//        }
//        for (int i = 0; i < group; i++) {
//            //先查看设备在不在线
//            byte[] data = null;
//            if(i==group-1){
//                data = new byte[remainder];
//            }
//            StringBuilder sb = new StringBuilder();
//            for(int j=0;j<25;j++){
//                sb.append(list.get(i*25+j).getIcId());
//                if(i*25+j==size-1){
//                    break;
//                }
//            }
//            if (UsrApi.getDevice(deviceId)) {
//                publishForDevId(PublishFormat(QRGenerate.parse16Str2HexByte(sb.toString()), GuardConstant.TYPE_ADD),deviceId);
//            }
//            if(group>2){
//                Thread.sleep(10000);
//            }
//        }
//        }catch(Exception e){
//            e.printStackTrace();
//            Log.error("IC卡插入失败，"+e.getMessage());
//            return false;
//        }

    //异步发送，每次最多发送25个  100个字节
    //暂时不异步，同步代替
//            CompletableFuture.supplyAsync(() -> {
//                try {
//
//                } catch (Exception e) {
//                    //TODO 插入失败，结果处理
//                    e.printStackTrace();
//                }
//                return true;
//            });
//    }
    public static void main(String[] args) {
        try {
            // 85 1 18 0 0 0 1 105
            /*
            String d = "55,01,12,00,00,00,01,69";
            String[] i = d.split(",");
            byte[] b = new byte[i.length];
            for (int r=0;r<i.length;r++){
                b[r] = Integer.valueOf(i[r], 16).byteValue();
            }*/
            //UsrUtil.SubscribeForUsername();
            //System.out.println((byte)(32));
            // System.out.println(Integer.toHexString(4));
            // getInstance().SubscribeForUsername();
            List<GuardIcInfo> list = new ArrayList<>();
            for (int i = 0; i < 28; i++) {
                GuardIcInfo ic = new GuardIcInfo();
                ic.setIcId(i + "" + i + "" + i + "" + i + "" + i + "" + i + "" + i + "" + i);
                list.add(ic);
            }
            //addIcToDev(list,"qw2121212");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
